package com.fmatos.controller;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheConfig;

import com.fmatos.controller.directory.AlbumDirectory;
import com.fmatos.service.album.domain.Album;
import com.fmatos.service.album.downloader.ImageDownloader;
import com.fmatos.service.album.downloader.info.AlbumInfo;
import com.fmatos.service.album.downloader.rss.AbstractRssDownloader;
import com.fmatos.service.album.downloader.rss.CustomRssDownloader;


/**
 * Provides a caching mechanism for albums response, in order to 
 * get faster response times for repeated requests.
 * @author fdematos
 *
 */
public class AlbumsCache {
	private static final Logger LOGGER = LoggerFactory.getLogger(AlbumsCache.class);

	private Map<String, CachedAlbum> albumsCache;
	
	public AlbumsCache() {
		albumsCache = new ConcurrentHashMap<String,CachedAlbum>();
	}	

	/**
	 * Gets an album from provided albumInfo, after having searched for that album info in the albums directory and also
	 * having looked for the album response in the internal cache
	 * @param albumInfo
	 * @return
	 */
	public Album getAlbum(AlbumInfo albumInfo) {

		CachedAlbum cachedAlbum = albumsCache.get(albumInfo.getName());
		
		if (cachedAlbum == null || cachedAlbum.updateTime.plusHours(2).isBeforeNow() ) {
			cachedAlbum = new CachedAlbum();
			
			cachedAlbum.albumInfo = buildDownloader(albumInfo); //new CustomRssDownloader(rssUrl);  // TODO ask directory
			cachedAlbum.downloader = cachedAlbum.albumInfo.getDownloader();
			cachedAlbum.album = cachedAlbum.downloader.getRandomAlbum();
			cachedAlbum.updateTime = new DateTime();
			
			
			albumsCache.put(cachedAlbum.albumInfo.getName(), cachedAlbum);
		}

		return cachedAlbum.album;
	}

	/**
	 * Tries to find an album in the directory that matches given album info
	 * @param albumInfo
	 * @return album info from the directory if it exists, or provided album info if it's not available
	 */
	private AlbumInfo buildDownloader(AlbumInfo albumInfo) {

		AlbumInfo albumInfoFromDirectory = AlbumDirectory.findAlbumByName(albumInfo.getName());

		AbstractRssDownloader downloader = null;
		if ( albumInfoFromDirectory != null ) {
			LOGGER.info("Directory found album info for {}", albumInfo.getNiceName());
			return albumInfoFromDirectory;
		} else {
			LOGGER.info("Directory couldn't find album info for {}", albumInfo.getNiceName());
			return albumInfo;
		}
		
	}

	private class CachedAlbum {
		public AlbumInfo albumInfo;
		
		public ImageDownloader downloader;
		
		public Album album;
		public DateTime updateTime;
		
		
	}
}
